package com.lam.schedule.common.config;

import java.util.Properties;

import javax.sql.DataSource;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.lam.common.config.AppBaseConfig;
import com.lam.common.utils.IpUtils;
import com.lam.schedule.common.scheduler.model.ScheduleProperties;

/**
 * 定时任务配置
 * 
 * @author lam
 */
@Configuration
public class ScheduleConfig {
	
	@Bean
	@ConfigurationProperties(prefix = "schedule")
	public ScheduleProperties createScheduleProperties() {
		return new ScheduleProperties();
	}
	
	/**
	 * quartz配置
	 */
	@Bean
	public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource, ScheduleProperties scheduleProp, AppBaseConfig appBaseConfig) {
		
		String schedulerName = String.format("%sScheduler%s", appBaseConfig.getName(), scheduleProp.isClustered()?"Cluster":"Single");
		String schedulerId = String.format("%s-%s.%s", IpUtils.getHostIp(), IpUtils.getHostName(), IdWorker.getIdStr());
		SchedulerFactoryBean factory = new SchedulerFactoryBean();
		factory.setSchedulerName(schedulerName);
		factory.setStartupDelay(1);// 延时启动
		factory.setApplicationContextSchedulerContextKey("applicationContextKey");
		// 可选，QuartzScheduler启动时更新己存在的Job，这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了
		factory.setOverwriteExistingJobs(true);
		// 设置自动启动，默认为true
		factory.setAutoStartup(true);
		Properties properties = new Properties();
		factory.setQuartzProperties(properties);
		// 线程池配置
		properties.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
		properties.put("org.quartz.threadPool.threadCount", scheduleProp.getThreadCount());
		properties.put("org.quartz.threadPool.threadPriority", scheduleProp.getThreadPriority());
		
		// quartz参数
		properties.put("org.quartz.scheduler.instanceName", schedulerName);
		properties.put("org.quartz.scheduler.instanceId", schedulerId);
//		prop.put("org.quartz.scheduler.instanceId", "AUTO");
		// JobStore配置
		if(scheduleProp.isRamJobStore()) {
			// RAMJobStore不支持集群配置
			properties.put("org.quartz.jobStore.class", "org.quartz.simpl.RAMJobStore");
		}else {
			factory.setDataSource(dataSource);
			properties.put("org.quartz.jobStore.class", "org.springframework.scheduling.quartz.LocalDataSourceJobStore");
			// 集群配置
			properties.put("org.quartz.jobStore.isClustered", String.valueOf(scheduleProp.isClustered()));
			properties.put("org.quartz.jobStore.clusterCheckinInterval", "15000");
			properties.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1");
			properties.put("org.quartz.jobStore.txIsolationLevelSerializable", "true");
			//拉取待即将触发的triggers时，需要上锁
			properties.put("org.quartz.jobStore.acquireTriggersWithinLock", "true");
			// sqlserver 启用
			// prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKSUPDLOCK WHERE LOCK_NAME = ?");
			properties.put("org.quartz.jobStore.misfireThreshold", "12000");
			properties.put("org.quartz.jobStore.tablePrefix", "qrtz_");
		}
		return factory;
	}
	
}
